#include "sdkconfig.h"

#include <stdio.h>
#include <cmath>
#include <vector>
#include <atomic>
#include <functional>
#include <algorithm>

#include <nvs.h>
#include <nvs_flash.h>

#include <esp_log.h>
#include <esp_err.h>
#include <esp_timer.h>
#include <esp_heap_caps.h>
#include <esp_event.h>
#include <esp_system.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include <ssid_manager.h>
#include <wifi_configuration_ap.h>
#include <wifi_station.h>
#define TAG "MAIN"

void WifiConfig() {
    ESP_LOGI(TAG, "开始WiFi配网");
    // 启动WiFi配置AP
    auto& wifi_ap = WifiConfigurationAp::GetInstance();
    wifi_ap.SetSsidPrefix("AI-PHONE");
    wifi_ap.Start();
}

extern "C" void app_main(void)
{
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);


    //检查是否有已配置的WiFi SSID
    auto& ssid_list = SsidManager::GetInstance().GetSsidList();
    if (ssid_list.empty()) {
        ESP_LOGI(TAG, "没有配置过WiFi SSID");
        WifiConfig();
        return;
    }

    // // 连接WiFi网络
    auto& wifi_station = WifiStation::GetInstance();
    wifi_station.OnScanBegin([]() {
        ESP_LOGI(TAG, "正在扫描WiFi网络...");
    });
    wifi_station.OnScanDown([](uint16_t ap_num, wifi_ap_record_t* ap_records) {
        ESP_LOGI(TAG, "扫描WiFi网络完成");
        if (ap_num == 0) {
              ESP_LOGI(TAG, "Nothing AP found");
              return;
        }//如果apCount没有受到数据，则说明没有路由器
        int i;
        ESP_LOGI(TAG,"======================================================================");
        ESP_LOGI(TAG,"             SSID             |    RSSI    |           AUTH           ");
        ESP_LOGI(TAG,"======================================================================");
        for (i=0; i<ap_num; i++) {
            char *authmode;
            switch(ap_records[i].authmode) {
            case WIFI_AUTH_OPEN:
                authmode = "WIFI_AUTH_OPEN";
                break;
            case WIFI_AUTH_WEP:
                authmode = "WIFI_AUTH_WEP";
                break;           
            case WIFI_AUTH_WPA_PSK:
                authmode = "WIFI_AUTH_WPA_PSK";
                break;           
            case WIFI_AUTH_WPA2_PSK:
                authmode = "WIFI_AUTH_WPA2_PSK";
                break;           
            case WIFI_AUTH_WPA_WPA2_PSK:
                authmode = "WIFI_AUTH_WPA_WPA2_PSK";
                break;
            default:
                authmode = "Unknown";
                break;
            }
            ESP_LOGI(TAG,"%26.26s    |    % 4d    |    %22.22s",ap_records[i].ssid, ap_records[i].rssi, authmode);
        }//将链表的数据信息打印出来
    });
    wifi_station.OnConnect([](const std::string& ssid) {
        ESP_LOGI(TAG, "正在连接到WiFi...");
    });
    wifi_station.OnConnected([](const std::string& ssid) {
        ESP_LOGI(TAG, "已连接到WiFi");
    });
    wifi_station.Start();

    if (!wifi_station.WaitForConnected(60 * 1000)) {
      wifi_station.Stop();
      ESP_LOGW(TAG, "连接WIFI失败,进入配网模式");
      WifiConfig();
      return;
    } 
    ESP_LOGI(TAG, "WIFI连接成功,ap:%s", wifi_station.GetSsid().c_str());
}
